home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
util
/
cdity
/
ModeProSrc.lha
/
Daemon
/
OldPatch
/
LockPubScreenListPatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-10
|
4KB
|
149 lines
//#define DEBUG
#include "MP.h"
#include <debug.h>
#include <exec/lists.h>
extern struct MPSem *MPSem;
// LockPubScreenList
extern struct List * __asm (*OldLockPubScreenList)(register __a6 struct Library *);
extern void __asm (*OldUnlockPubScreenList)(register __a6 struct Library *);
struct List PubScreenList;
LONG PubListNest=0; // If Zero then Init
#define PSNF_FAKE (1<<15) // Fake psn_Flags
struct List *IntuitionPubScreenList;
struct List * __saveds __asm NewLockPubScreenList(register __a6 struct IntuitionBase *IBase)
{
struct PubScreenNode *psn,*npsn;
struct DefaultNode *dnode;
struct List *list;
struct Task faketask={0};
struct Screen *fakescr;
char tnamebuffer[52];
char *tname;
tname=SetupTaskName(tnamebuffer,", LPSL",50);
DEBUG_CODE(
DKP("LockPubScreenList()\n");
)
ObtainSemaphoreShared(&MPSem->ListSem);
ObtainSemaphore(&MPSem->NodeSem);
IntuitionPubScreenList=list=OldLockPubScreenList((struct Library *)IBase);
/* Clone Old PS list */
if(PubListNest==0)
{
// The OS nests calls to LockPubScreenList()/UnlockPubScreenList() only create the list when PubListNest==0
/* Make PSNodes for MP's pubscreens */
dnode=(struct DefaultNode *)MPSem->PromotionList[PL_PUBLICSCREENS].lh_Head;
psn=(APTR)list->lh_Head;
if(psn->psn_Node.ln_Succ)
{
while(dnode->Def_Node.ln_Succ)
{
if(!FindName(list,dnode->Def_Node.ln_Name))
{ /* Avoid Duplicates */
if(npsn=AllocVec(sizeof(*npsn),MEMF_PUBLIC|MEMF_CLEAR))
{
if(fakescr=AllocVec(sizeof(*fakescr),MEMF_PUBLIC|MEMF_CLEAR))
{
/* Screen */
fakescr->Width=dnode->Width;
fakescr->Height=dnode->Height;
fakescr->Title=dnode->Def_Node.ln_Name;
fakescr->RastPort.BitMap=&fakescr->BitMap;
fakescr->BitMap.Depth=dnode->Depth;
npsn->psn_Node.ln_Name=dnode->Def_Node.ln_Name; // Safe to reference name since lists are protected till UnlockPubScreenList()
npsn->psn_Flags=PSNF_FAKE;
npsn->psn_SigTask=&faketask;
npsn->psn_Screen=fakescr; // Hmmm
AddTail(list,(struct Node *)npsn);
}
else
{
FreeVec(npsn);
}
}
}
dnode=(struct DefaultNode *)dnode->Def_Node.ln_Succ;
}
}
}
else
{
// nested
}
/*
{
LONG *l,q;
l=0;
*l=0;
}*/
PubListNest++; // Some dumb apps call LockPubScreen() inside LockPubScreenList()/UnlockPubScreenList()
SetTaskName(tname);
return(list);
}
void __saveds __asm NewUnlockPubScreenList(register __a6 struct IntuitionBase *IBase)
{
struct PubScreenNode *psn,*p2;
PubListNest--;
if(PubListNest==0)
{
psn=(APTR)IntuitionPubScreenList->lh_Head;
while(psn->psn_Node.ln_Succ)
{
DKP("psn=%8lx %s\n",psn,psn->psn_Node.ln_Name);
if(psn->psn_Flags & PSNF_FAKE)
{
DKP(" free psn\n");
p2=(APTR)psn->psn_Node.ln_Succ;
Remove((APTR)psn);
FreeVec(psn->psn_Screen); // screen is fake to!
FreeVec(psn);
psn=p2;
}
else
{
psn=(APTR)psn->psn_Node.ln_Succ;
}
}
}
OldUnlockPubScreenList((struct Library *)IBase);
DEBUG_CODE(
DKP("UnlockPubScreenList()\n");
)
ReleaseSemaphore(&MPSem->NodeSem);
ReleaseSemaphore(&MPSem->ListSem);
}